package cn.wp.common.core.util;

import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.wp.common.core.exception.WpException;

import java.util.List;
import java.util.Map;

/**
 * 属性拷贝
 * Created by chenyb on 2019/09/29
 */
public class BeanUtil {

    public static abstract class Processor<S,T> {
        /**
         * 转换
         * @param source
         * @param target
         */
        public abstract void convert(S source,T target);
    }

    public static <S,T> T copyProperties(S source,Class<T> target){
        try {
            if(source == null) {
                return null;
            }
            Object newInstance = target.newInstance();
            cn.hutool.core.bean.BeanUtil.copyProperties(source,newInstance);
            return (T)newInstance;
        }catch (Exception ex){
            throw new WpException("属性拷贝出错",ex);
        }
    }

    public static <S,T> T copyProperties(S source,Class<T> target,Processor processor){
        if(source == null) {
            return null;
        }
        Object newInstance = copyProperties(source,target);
        processor.convert(source,newInstance);
        return (T)newInstance;
    }

    public static <S,T> List<T> listCopyProperties(List<S> sources,Class<T> target){
        try {
            List<T> list = CollectionUtil.newArrayList();
            for (S object : sources){
                Object newInstance = target.newInstance();
                cn.hutool.core.bean.BeanUtil.copyProperties(object,newInstance);
                list.add((T)newInstance);
            }
            return list;
        }catch (Exception ex){
            throw new WpException("属性拷贝出错",ex);
        }
    }

    public static <S,T> List<T> listCopyProperties(List<S> sources,Class<T> target,Processor processor){
        try {
            List<T> list = CollectionUtil.newArrayList();
            for (Object object : sources){
                Object newInstance = target.newInstance();
                cn.hutool.core.bean.BeanUtil.copyProperties(object,newInstance);
                processor.convert(object,newInstance);
                list.add((T)newInstance);
            }
            return list;
        }catch (Exception ex){
            throw new WpException("属性拷贝出错",ex);
        }
    }

    public static <S,T> T mapToBean(Map<String,S> data,Class<T> beanClass){
        return cn.hutool.core.bean.BeanUtil.mapToBean(data,beanClass,new CopyOptions());
    }

    public static Map<String,Object> beanToMap(Object bean){
        return cn.hutool.core.bean.BeanUtil.beanToMap(bean);
    }

    public static <T> List<T> listMapToBean(List<Map<String,Object>> data,Class<T> beanClass){
        try {
            List<T> list = CollectionUtil.newArrayList();
            for (Map<String,Object> map : data){
                T newInstance = cn.hutool.core.bean.BeanUtil.mapToBean(map,beanClass, new CopyOptions());
                list.add((T)newInstance);
            }
            return list;
        }catch (Exception ex){
            throw new WpException("属性拷贝出错",ex);
        }
    }

    public static <T> List<T> listMapToBean(List<Map<String,Object>> data,Class<T> beanClass,Processor processor){
        try {
            List<T> list = CollectionUtil.newArrayList();
            for (Map<String,Object> map : data){
                T newInstance = cn.hutool.core.bean.BeanUtil.mapToBean(map,beanClass, new CopyOptions());
                processor.convert(map,newInstance);
                list.add((T)newInstance);
            }
            return list;
        }catch (Exception ex){
            throw new WpException("属性拷贝出错",ex);
        }
    }

    public static List<Map<String,Object>> listBeaToMap(List<Object> beanList){
        try {
            List<Map<String,Object>> list = CollectionUtil.newArrayList();
            for (Object bean : beanList){
                Map<String,Object> obj = cn.hutool.core.bean.BeanUtil.beanToMap(bean);
                list.add(obj);
            }
            return list;
        }catch (Exception ex){
            throw new WpException("属性拷贝出错",ex);
        }
    }

    public static <T> List<Map<String,Object>> listBeaToMap(List<T> beanList,Processor processor){
        try {
            List<Map<String,Object>> list = CollectionUtil.newArrayList();
            for (T bean : beanList){
                Map<String,Object> obj = cn.hutool.core.bean.BeanUtil.beanToMap(bean);
                processor.convert(bean,obj);
                list.add(obj);
            }
            return list;
        }catch (Exception ex){
            throw new WpException("属性拷贝出错",ex);
        }
    }

}

